#region Imported Namespaces


using System.Drawing;
using System.IO;

using WtfManager.HierarchicalData;
using WtfManager.WindowsNative.Shell32;

using FileInfo=WtfManager.WindowsNative.Shell32.FileInfo;


#endregion


namespace WtfManager.FileManager
{
  ///<summary>
  /// A base class for file system items.
  ///</summary>
  public abstract class FileSystemItem: TreeItem
  {
    #region Properties/Indexers


    ///<summary>
    /// Gets file system path of an item.
    ///</summary>
    public string FileSystemPath
    {
      get
      {
        return GetFileSystemPath();
      }
    }

    public abstract bool IsFile
    {
      get;
    }

    public abstract bool IsHidden
    {
      get;
    }


    ///<summary>
    /// Returns file system icon.
    ///</summary>
    public Icon LargeIcon
    {
      get
      {
        const FileInfo flags = FileInfo.SHGFI_ICON | FileInfo.SHGFI_ADDOVERLAYS | FileInfo.SHGFI_LARGEICON;

        return GetIcon(flags);
      }
    }


    ///<summary>
    /// Returns file system icon.
    ///</summary>
    public Icon SmallIcon
    {
      get
      {
        const FileInfo flags = FileInfo.SHGFI_ICON | FileInfo.SHGFI_ADDOVERLAYS | FileInfo.SHGFI_SMALLICON;

        return GetIcon(flags);
      }
    }


    #endregion


    #region Methods


    ///<summary>
    /// Gets an icon of a file system item.
    ///</summary>
    ///<returns>Returns <see cref="Icon"/>.</returns>
    protected abstract Icon GetIcon(FileInfo flags);


    ///<summary>
    /// Gets file system path of an item.
    ///</summary>
    ///<returns>a string containing file system path of an item.</returns>
    protected virtual string GetFileSystemPath()
    {
      if (Parent != null && Parent is FileSystemItem)
      {
        string parentPath = ((FileSystemItem)Parent).GetFileSystemPath();

        if (!string.IsNullOrEmpty(parentPath))
        {
          return parentPath + Name;
        }
      }

      return Name;
    }


    ///<summary>
    ///Returns a <see cref="T:System.String" /> that represents the current <see cref="T:System.Object" />.
    ///</summary>
    ///<returns>
    ///A <see cref="T:System.String" /> that represents the current <see cref="T:System.Object" />.
    ///</returns>
    public override string ToString()
    {
      return Name;
    }


    /// <summary>
    /// Moves the current item to the specified destination folder.
    /// </summary>
    /// <param name="destinationFolder">An instance of a <see cref="WtfManager.FileManager.FileSystemFolder"/>.</param>
    public void Move(FileSystemFolder destinationFolder)
    {
      ValidateMoveTo(destinationFolder);

      string destination = System.IO.Path.Combine(destinationFolder.FileSystemPath, Name);
      Directory.Move(FileSystemPath, destination);

      var parentItem = ((FileSystemItem)Parent);
      parentItem.RemoveChild(this);
      destinationFolder.AddChild(this);

      Refresh();
    }


    public virtual Pidl GetPidl(FileInfo flags)
    {
      return new Pidl(FileSystemPath, flags);
    }


    #endregion
  }
}